package cn.edu.sdjzu.knoverse.controller;

import cn.edu.sdjzu.knoverse.constant.RedisUserConstant;
import cn.edu.sdjzu.knoverse.model.dto.system.user.AdminUserUpdateByLocalUserDto;
import cn.edu.sdjzu.knoverse.model.dto.system.user.LoginDto;
import cn.edu.sdjzu.knoverse.model.dto.system.user.UserPasswordUpdateDto;
import cn.edu.sdjzu.knoverse.model.vo.result.Result;
import cn.edu.sdjzu.knoverse.model.vo.result.ResultCodeEnum;
import cn.edu.sdjzu.knoverse.model.vo.system.user.LoginVo;
import cn.edu.sdjzu.knoverse.service.UserService;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.core.util.IdUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Tag(name = "认证", description = "登录认证相关接口")
@RestController
@RequestMapping("/auth")
public class AuthController {
    @Resource
    private UserService userService;
    
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Operation(summary = "登录", description = "用户登录")
    @PostMapping("/login")
    public Result<LoginVo> login(@Valid @RequestBody LoginDto dto) {
        // 验证验证码
        String captchaCode = dto.getCaptchaCode();
        String captchaKey = dto.getCaptchaKey();
        
        if (captchaKey == null || captchaKey.isEmpty()) {
            return Result.error(ResultCodeEnum.CAPTCHA_ERROR);
        }
        
        Object codeCached = redisTemplate.opsForValue().get(RedisUserConstant.getCaptchaCodeKey(captchaKey));
        
        if (codeCached == null) {
            return Result.error(ResultCodeEnum.CAPTCHA_EXPIRED);
        }
        
        if (!captchaCode.equalsIgnoreCase((String) codeCached)) {
            return Result.error(ResultCodeEnum.CAPTCHA_ERROR);
        }
        
        // 验证码使用后删除
        redisTemplate.delete(RedisUserConstant.getCaptchaCodeKey(captchaKey));
        
        // 验证码正确，执行登录
        LoginVo vo = userService.login(dto);
        return Result.success(vo);
    }

    @Operation(summary = "获取本地登录用户信息", description = "获取用户信息从Redis中获取")
    @GetMapping("noManage/getUserinfo")
    public Result<LoginVo> getUserinfo() {
        LoginVo vo = userService.getUserinfo();
        return Result.success(vo);
    }

    @Operation(summary = "更新本地用户信息", description = "更新本地用户信息，需要更新Redis中的内容")
    @PutMapping("noManage/updateAdminUserByLocalUser")
    public Result<String> updateAdminUserByLocalUser(@Valid @RequestBody AdminUserUpdateByLocalUserDto dto) {
        userService.updateAdminUserByLocalUser(dto);
        return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
    }
    
    @Operation(summary = "更新本地用户头像", description = "更新本地用户头像，先上传文件再更新用户信息")
    @PostMapping("noManage/updateAvatarByLocalUser")
    public Result<String> updateAvatarByLocalUser(@RequestParam("file") MultipartFile file) {
        userService.updateAvatarByLocalUser(file);
        return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
    }

    @Operation(summary = "更新本地用户密码", description = "更新本地用户密码")
    @PutMapping("noManage/updateUserPasswordByLocalUser")
    public Result<String> updateUserPasswordByLocalUser(@Valid @RequestBody UserPasswordUpdateDto dto) {
        userService.updateUserPasswordByLocalUser(dto);
        return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
    }

    @Operation(summary = "退出登录", description = "退出登录")
    @PostMapping("noManage/logout")
    public Result<String> logout() {
        userService.logout();
        return Result.success(ResultCodeEnum.LOGOUT_SUCCESS);
    }

    @Operation(summary = "生成验证码", description = "生成验证码")
    @GetMapping("noAuth/checkCode")
    public Result<Map<String, Object>> checkCode() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_JPEG);

        // 生成验证码，4位，干扰线为2
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(150, 48, 4, 2);
        String code = captcha.getCode();
        String imageBase64 = captcha.getImageBase64Data();
        
        // 生成唯一标识
        String captchaKey = IdUtil.simpleUUID();
        
        // 将验证码存入Redis，设置5分钟过期
        redisTemplate.opsForValue().set(
                RedisUserConstant.getCaptchaCodeKey(captchaKey),
                code,
                RedisUserConstant.CAPTCHA_CODE_EXPIRE,
                TimeUnit.SECONDS
        );
        
        // 返回验证码图片Base64编码和唯一标识
        Map<String, Object> result = new HashMap<>();
        result.put("captchaImage", imageBase64);
        result.put("captchaKey", captchaKey);
        
        return Result.success(result);
    }
}
